/*

Introduction
____________


Project WOF (Walk On the Fire) was initiated to make a robust solution
to evaluatge different Web Application Firewalls(WAF) without putting or
enabling in-line mode of any WAF. This code is tested with the mod_Security,
naxsi and with some other commercial WAF. This engine is in-sufficient to
handle phase-3 and phase-4 requests (Working to resolve this issue).

To read more Reach me @: http://bhaumikmerchant.in/
To read Official Blog of WOF Reachout @: http://bhaumikmerchant.in/w-o-f.htm

Feel Free to ask me about any installation issue :)
Mail me @ wof[dot]bhaumik[dot]merchant [at]gmail[dot]com

Dependencies
____________

HTTP_Client 4.2.5  (Download From : http://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient/4.2.5 )
JPCAP 0.7   (Download From (Mirror) : http://www.eden.rutgers.edu/~muscarim/jpcap/download.html ) 

( Note: Instead of entering url like "http://example.com" enter only "example.com or www.example.com", don't worry
	  about "http://" and "trailing slash")
 */
	/**
	 *
	 * @param args
	 * @author Bhaumik Merchant
	 */

import java.io.*;
import jpcap.*;
import jpcap.packet.*;
import java.util.*;
import org.apache.http.HttpResponse;
import javax.swing.*;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.net.URI;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import java.net.URLDecoder;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.client.methods.HttpGet;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;


class Engine extends PassiveEngine implements PacketReceiver
{
    public void receivePacket(Packet p) 
	{
	    if(p instanceof TCPPacket)
	   {
	      TCPPacket tcp = (TCPPacket)p;
		  int sport = tcp.src_port;
		  int dport = tcp.dst_port;
		  
		  
		      if(sport == 80 || dport == 80)
			  {
				  byte[] b= p.header;	
				  String d = "";					
				   try
				   {
						d= new String(b,"UTF-8");
				   }
				   catch(Exception edata)	
				   {
						System.out.print("\n EXCEPTION IN DECODING HEADER: "+edata);
				   }
					byte[] packetData = p.data;
				    String jk = "";
					
				    try
					{
						jk = new String(packetData,"UTF-8");
					}
					catch(Exception ehdr)
					{
						System.out.print("\n EXCEPTION IN DECODING PAYLOAD: "+ehdr);
					}
					String temp_jk = jk;

			if(jk.startsWith("get") || jk.startsWith("GET") )
			{
			  String get_dummy = jk;
			  StringTokenizer st2 = new StringTokenizer(get_dummy.toLowerCase(), "\n");
			  StringTokenizer st3 = new StringTokenizer(jk, "\n");
			  
			  String newuri = "";
			  String newhost = "";
			  String getreq = "";
			  String newconnection = "";
			  String new_user_agent = "";
			  String new_accept_encoding = "";
			  String new_accept_language = "";
			  String newaccept = "";
			  String newcookie = "";
			  String newaccept_charset = "";
			  String newreferer = "";
			  while (st2.hasMoreElements()) 
			  {
				  		String te1 = st2.nextElement().toString();
				  		String te = st3.nextElement().toString();
				  		
						if(te1.startsWith("get"))
						{
							newuri = te.substring(te.indexOf(" ")+1,te.lastIndexOf(" "));
							getreq = newuri;
						}
						if(te1.startsWith("host"))
						{
							newhost = te.substring(te.indexOf(" ")+1,te.length()-1);
							getreq = newhost+getreq;
						}
						if(te1.startsWith("connection"))
						{
							newconnection = te.substring(te.indexOf(" ")+1,te.length()-1);
							newconnection = newconnection.trim();
						}
						if(te1.startsWith("accept:"))
						{
							newaccept = te.substring(te.indexOf(" ")+1,te.length()-1);
						}
						if(te1.startsWith("user-agent"))
						{
						   new_user_agent = te.substring(te.indexOf(" ")+1,te.length()-1);	
						}
						if(te1.startsWith("referer"))
						{
						   newreferer = te.substring(te.indexOf(" ")+1,te.length()-1);	
						}
						
						if(te1.startsWith("accept-encoding"))
						{
							new_accept_encoding = 	te.substring(te.indexOf(" ")+1,te.length()-1);
						}
						if(te1.startsWith("accept-language"))
						{
							new_accept_language = te.substring(te.indexOf(" ")+1,te.length()-1);
						}						
						if(te1.startsWith("accept-charset"))
						{
							newaccept_charset = te.substring(te.indexOf(" ")+1,te.length()-1);
						}
						if(te1.startsWith("cookie"))
						{
							newcookie = te.substring(te.indexOf(" ")+1,te.length()-1);
						}


				}
			  String throw_url = "http://"+wafbox+newuri;
			  String result = "";
			  try
			  {
				  result = URLDecoder.decode(throw_url, "UTF-8");
			  }
			  catch(Exception decode)
			  {
				  System.out.println("\n EXCEPTION IN DECODING  : "+decode);
			  }
			  

			  try
			  {
			   if(newuri.endsWith("css")||newuri.endsWith("ico")||newuri.endsWith("#")||newuri.endsWith("xls")||newuri.endsWith("jar")||newuri.endsWith("png") || newuri.endsWith("exe") || newuri.endsWith("js") || newuri.endsWith("bmp") || newuri.endsWith("gif") || newuri.endsWith("jpg") || newuri.endsWith("jpeg") || newuri.endsWith("tiff")|| newuri.endsWith("mid")|| newuri.endsWith("mp2")|| newuri.endsWith("mp3")|| newuri.endsWith("mp4")|| newuri.endsWith("wav")|| newuri.endsWith("avi")|| newuri.endsWith("mov")|| newuri.endsWith("mpeg")|| newuri.endsWith("ram")|| newuri.endsWith("m4v")|| newuri.endsWith("pdf")|| newuri.endsWith("rm")|| newuri.endsWith("smil")|| newuri.endsWith("wmv")|| newuri.endsWith("swf")|| newuri.endsWith("wma")|| newuri.endsWith("zip")|| newuri.endsWith("rar"))
			   {
				   
			   }
			   else
			   {

				if(newhost.equals(lockurl))
				{
					String gone = result;
					System.out.print("\n HTTP GET REQUEST          : "+result);
					
					URL url = new URL(result);
			        URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
			        String tres = uri.toURL().toString();

			        int tra = uri.toString().indexOf(uri.getPath().toString());
			        String URI_PATH = uri.toString().substring(tra+1,uri.toString().length());
			        HttpClient client = new DefaultHttpClient();
					HttpGet request = new HttpGet(tres);
					request.addHeader("Host",wafbox);
					request.addHeader("Connection",newconnection);
					request.addHeader("Accept",newaccept);
				    request.addHeader("User-Agent", new_user_agent);
	   			    if(newreferer!=null)
					{
					  	request.addHeader("Referer",newreferer);
				    }
	   			    request.addHeader("Accept-Encoding",new_accept_encoding);
 	    		    request.addHeader("Accept-Language",new_accept_language);
	   			    request.addHeader("Accept-Charset",newaccept_charset);
					request.addHeader("Cookie",newcookie);
					
					String sip = tcp.src_ip.toString();
					long lStartTime = System.nanoTime();
					HttpResponse response = client.execute(request);
					long lEndTime = System.nanoTime();
					long difference = lEndTime - lStartTime;
					int code =response.getStatusLine().getStatusCode();

					System.out.print("\n HTTP STATUS CODE FOR GET  : "+code);
					System.out.println("\n PROCESSING TIME TAKEN     : "+difference/1000000+" msec");
					System.out.println("\n################################################################################");
					
					fn = new File(fname);
					fw = new FileWriter(fn,true);		
					fw.write("\n HTTP GET REQUEST          : "+gone);
					fw.write("\n HTTP STATUS CODE FOR GET  : "+code);
					fw.write("\n PROCESSING TIME TAKEN     : "+difference/1000000+" msec");
					fw.write("\n################################################################################\n");
					fw.close();
					System.out.println();
					
				 }
				}
			  }
			  catch(Exception try_C)
			  {

				  StringWriter writer = new StringWriter();
				  PrintWriter printWriter = new PrintWriter( writer );
				  try_C.printStackTrace( printWriter );
				  printWriter.flush();
				  String stackTrace = writer.toString();
				  
				  System.out.print("\n DEEPER DIVE : "+stackTrace);
				  System.out.print("\n EXCEPTION IN TRY_C : "+ try_C);
			  }
			  
			}
			if(jk.startsWith("post") || jk.startsWith("POST"))
		    {

		      String post_dummy = jk;
			  StringTokenizer st2 = new StringTokenizer(post_dummy, "\n");
			  StringTokenizer st3 = new StringTokenizer(jk, "\n");
			  
			  ArrayList<String> http = new ArrayList<String>();
			  String newuri = "";
			  String host = "";
			  String connection = "";
			  String cc = "";
			  String cl = "";
			  String accept = "";
			  String origin = "";
			  String user_agent = "";
			  String ct = "";
			  String ae = "";
			  String al = "";
			  String referer = "";
			  String ac = "";
			  String cookie = "";
			  String post_payload = "";
			  
			  while (st2.hasMoreElements()) 
			  {
				   String te = st2.nextElement().toString();
				   te =te.trim();
				   if(te.contains("&")==true && te.contains("=")==true)
				   {
					   post_payload = te;
				   }
				   if(te.toLowerCase().startsWith("post") == true)
				   {
					newuri = te.substring(te.indexOf(" ")+1,te.lastIndexOf(" "));
					http.add(newuri);
				   }

				   if(te.toLowerCase().contains("host: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("host: ");
					    String tree = te.substring(base12+6,te.length());
					    tree.trim();
					    http.add(tree);
					    host = tree;
				   }
				   if(te.toLowerCase().contains("connection: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("connection: ");
					    String tree = te.substring(base12+12,te.length());
					    tree.trim();
					    connection = tree;
				   }

				   if(te.toLowerCase().contains("content-length: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("content-length: ");
					    String tree = te.substring(base12+16,te.length());
					    tree.trim();
					    cl = tree;
				   }
				   if(te.toLowerCase().contains("cache-control: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("cache-control: ");
					    String tree = te.substring(base12+15,te.length());
					    tree.trim();
					    cc = tree;
				   }
				   if(te.toLowerCase().contains("accept: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("accept: ");
					    String tree = te.substring(base12+8,te.length());
					    tree.trim();
					    accept = tree;
				   }
				   if(te.toLowerCase().contains("origin: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("origin: ");
					    String tree = te.substring(base12+8,te.length());
					    tree.trim();
					    origin = tree;
				   }
				   if(te.toLowerCase().contains("user-agent: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("user-agent: ");
					    String tree = te.substring(base12+12,te.length());
					    tree.trim();
					    user_agent = tree;
				   }
				   if(te.toLowerCase().contains("content-type: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("content-type: ");
					    String tree = te.substring(base12+14,te.length());
					    tree.trim();
					    ct = tree;
				   }
				   if(te.toLowerCase().contains("referer: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("referer: ");
					    String tree = te.substring(base12+9,te.length());
					    tree.trim();
					    referer = tree;
				   }
				   if(te.toLowerCase().contains("accept-encoding: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("accept-encoding: ");
					    String tree = te.substring(base12+17,te.length());
					    tree.trim();
					    ae = tree;
				   }
				   if(te.toLowerCase().contains("accept-language: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("accept-language: ");
					    String tree = te.substring(base12+17,te.length());
					    tree.trim();
					   al = tree;
				   }
				   if(te.toLowerCase().contains("accept-charset: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("accept-charset: ");
					    String tree = te.substring(base12+16,te.length());
					    tree.trim();
					    ac = tree;
				   }
				   if(te.toLowerCase().contains("cookie: ") == true)
				   {
					   int base12 = te.toLowerCase().indexOf("cookie: ");
					    String tree = te.substring(base12+8,te.length());
					    tree.trim();
					    cookie = tree;
				   }
				   
				   
			  }
			  String throw_url = "http://"+wafbox+newuri;
			  String result = "";
			  try
			  {
				  result = URLDecoder.decode(throw_url, "UTF-8");
			  }
			  catch(Exception decode)
			  {
				  System.out.println("\n EXCEPTION IN DECODING  : "+decode);
			  }

			  if(newuri.endsWith("css")||newuri.endsWith("ico")||newuri.endsWith("#")||newuri.endsWith("xls")||newuri.endsWith("jar")||newuri.endsWith("png") || newuri.endsWith("exe") || newuri.endsWith("js") || newuri.endsWith("bmp") || newuri.endsWith("gif") || newuri.endsWith("jpg") || newuri.endsWith("jpeg") || newuri.endsWith("tiff")|| newuri.endsWith("mid")|| newuri.endsWith("mp2")|| newuri.endsWith("mp3")|| newuri.endsWith("mp4")|| newuri.endsWith("wav")|| newuri.endsWith("avi")|| newuri.endsWith("mov")|| newuri.endsWith("mpeg")|| newuri.endsWith("ram")|| newuri.endsWith("m4v")|| newuri.endsWith("pdf")|| newuri.endsWith("rm")|| newuri.endsWith("smil")|| newuri.endsWith("wmv")|| newuri.endsWith("swf")|| newuri.endsWith("wma")|| newuri.endsWith("zip")|| newuri.endsWith("rar"))
			   {
				   
			   }
			   else
			   {

				   lockurl = lockurl.trim();

				if(http.get(1).trim().equals(lockurl.trim()))
				{
					String gone= result;
					System.out.print("\n HTTP POST REQUEST         : "+result);	

					HttpClient client = new DefaultHttpClient();
					HttpPost post = new HttpPost(result);

					post.addHeader("Host",wafbox);
					post.addHeader("Connection",connection);
					post.addHeader("Cache-Control",cc);
					post.addHeader("Accept",accept);
					post.addHeader("Origin",origin);
					post.addHeader("User-Agent", user_agent);
					post.addHeader("Content-Type", ct);
					if(referer!=null)
					{
					  	post.addHeader("Referer",referer);
					}
					post.addHeader("Accept-Encoding",ae);
					post.addHeader("Accept-Language",al);
					post.addHeader("Accept-Charset",ac);					
					post.addHeader("Cookie",cookie);
					
				   		try 
					    {
							int index_m = temp_jk.lastIndexOf("\n");
							List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
							String post_params = temp_jk.substring(index_m+1,temp_jk.length());
							StringTokenizer param_split = new StringTokenizer(post_params, "&");
							  while (param_split.hasMoreElements()) 
							  {
								  		String terr = param_split.nextElement().toString();
								  		
								  		StringTokenizer param_split1 = new StringTokenizer(terr, "=");
								  		int ctl = 0;
								  		String sr1 = "";
								  		String sr2 = "";
								  tyu:  while (param_split1.hasMoreElements())
								  		{
								  			String terr1 = param_split1.nextElement().toString();
								  			if(ctl==0)
								  			{
								  				sr1 = terr1;
								  				ctl++;
								  				continue tyu;
								  			}
								  			if(ctl==1)
								  			{
								  				sr2 = terr1;
								  				sr2 = URLDecoder.decode(sr2, "UTF-8");
								  			}
								  		}
								  		nameValuePairs.add(new BasicNameValuePair(sr1,sr2));
								  		
								  		post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
							  }

						  post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
						  String sip = tcp.src_ip.toString();
						  long lStartTime = System.nanoTime();
					       HttpResponse response = client.execute(post);
							long lEndTime = System.nanoTime();
							long difference = lEndTime - lStartTime;
							int code =response.getStatusLine().getStatusCode();
							System.out.print("\n PARAMETER TO BE POST      : "+post_params);
							System.out.print("\n HTTP STATUS CODE FOR POST : "+code);
							System.out.println("\n PROCESSING TIME TAKEN     : "+difference/1000000+" msec");
							System.out.println("\n################################################################################");
							fn = new File(fname);
							fw = new FileWriter(fn,true);	
							fw.write("\n HTTP POST REQUEST         : "+result);
							fw.write("\n PARAMETER TO BE POST      : "+post_params);
							fw.write("\n HTTP STATUS CODE FOR POST : "+code);
							fw.write("\n PROCESSING TIME TAKEN     : "+difference/1000000+" msec\n");
							fw.write("\n################################################################################");
							fw.close();
							

					    } 
					    catch (Exception e) 
					    {
					      e.printStackTrace();
					      System.out.println("\n PROBLEM PROBLEM Q : "+e);
					      
					    }
				}
		     } 
			}
	   }
	   
	}

	}
}

public class PassiveEngine extends JFrame 
{

	/**
	 * @param args
	 * @author Bhaumik Merchant
	 */
	public static String lockurl = "";
	public static String wafbox = "";
	public static int choose = 0;
	public static int conf = 0;
	public static File fn;
	public static FileWriter fw ;
	public static String comma = ",";
	public static String fname = "";
	public static int caprute_flag=0;
	public static int select_nic = 0;

	public static void main(String[] st) throws Exception 
	{

		//@author Bhaumik Merchant
		
		DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy_HH-mm-ss");
		Date date = new Date();
		fname = dateFormat.format(date).toString()+".data";
		fn = new File(fname);
		fw = new FileWriter(fn,true);		
		fw.write("#######################################################################################################\n\n");
		fw.write("                            PROJECT WOF CAPTURE OUTPUT (AUTO-RAW-CAPTURE) \n\n\n");
		fw.write("                            Author : Bhaumik Merchant (http://bhaumikmerchant.in/ \n");
		fw.write("                            Official Blog : http://bhaumikmerchant.in/w-o-f.htm \n");
		fw.write("                            Google Code : http://code.google.com/p/w-o-f/ \n");
		fw.write("                            SourceForge : http://sourceforge.net/projects/w-o-f/ \n");
		fw.write("\n#######################################################################################################");
		fw.write("\n");
		fw.close();

		NetworkInterface[] devices = JpcapCaptor.getDeviceList();
			
			for (int i = 0; i < devices.length; i++) 
			{
				System.out.println(i+" :"+devices[i].name + "(" + devices[i].description+")");
				System.out.println("    data link:"+devices[i].datalink_name + "("
						+ devices[i].datalink_description+")");
				System.out.print("    MAC address:");
				for (byte b : devices[i].mac_address)
					System.out.print(Integer.toHexString(b&0xff) + ":");
				System.out.println();
				for (NetworkInterfaceAddress a : devices[i].addresses)
					System.out.println("    address:"+a.address + " " + a.subnet + " "
							+ a.broadcast);
			}
				BufferedReader b1234 = new BufferedReader(new InputStreamReader(System.in));
				System.out.print("\n Choose Interface : ");				
				select_nic = Integer.parseInt(b1234.readLine());				
				BufferedReader b123 = new BufferedReader(new InputStreamReader(System.in));
				System.out.print("\n LOCK PROFILE(Website) FOR PASSIVE ENGINE TO BE SET : ");
				lockurl = b123.readLine();
				System.out.print("\n ENTER WAF-BOX URL : ");
				wafbox = b123.readLine();
				try
				{
				JpcapCaptor jpcap = JpcapCaptor.openDevice(devices[select_nic], 2000, false, 20);
				jpcap.loopPacket(-1, new Engine());
				}
				catch(Exception er5)
				{
					System.out.println("\n PACKET SENDING EXCEPTION : "+er5);
				}
	}

}
